﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
//using System.Linq;
using System.Text;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;
using Nintex.Workflow;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace NPPTEC.WorkflowPowerShell
{


    public class ExecuteActivityCode : Activity
    {
        public static DependencyProperty CurrentWorkflowVariableValuesProperty =
             DependencyProperty.Register("CurrentWorkflowVariableValues", typeof(Hashtable),
                                         typeof(ExecuteActivityCode));

        public static DependencyProperty __ListItemProperty = DependencyProperty.Register("__ListItem", typeof(int),
                                                                                          typeof(ExecuteActivityCode));

        public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context",
                                                                                         typeof(WorkflowContext),
                                                                                         typeof(ExecuteActivityCode));

        public static DependencyProperty __ListIdProperty = DependencyProperty.Register("__ListId", typeof(string),
                                                                                        typeof(ExecuteActivityCode));


        public static DependencyProperty PowerShellInputProperty = DependencyProperty.Register("PowerShellInput", typeof(string),
                                                                                      typeof(ExecuteActivityCode));

        public static DependencyProperty PowerShellOutputProperty = DependencyProperty.Register("PowerShellOutput", typeof(string),
                                                                                          typeof(ExecuteActivityCode));



        public static DependencyProperty CaptureErrorsProperty = DependencyProperty.Register("CaptureErrors",
                                                                                             typeof(bool),
                                                                                             typeof(ExecuteActivityCode
                                                                                                 ));

        public static DependencyProperty ErrorOccurredOutputProperty = DependencyProperty.Register(
            "ErrorOccurredOutput", typeof(bool), typeof(ExecuteActivityCode));

        public static DependencyProperty ErrorMessageOutputProperty = DependencyProperty.Register("ErrorMessageOutput",
                                                                                                  typeof(string),
                                                                                                  typeof(
                                                                                                      ExecuteActivityCode
                                                                                                      ));

        [Browsable(true), ValidationOption(ValidationOption.Required),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public Hashtable CurrentWorkflowVariableValues
        {
            get { return (Hashtable)base.GetValue(CurrentWorkflowVariableValuesProperty); }
            set { base.SetValue(CurrentWorkflowVariableValuesProperty, value); }
        }

        [ValidationOption(ValidationOption.Required), Browsable(true),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int __ListItem
        {
            set { base.SetValue(__ListItemProperty, value); }
            get { return (int)base.GetValue(__ListItemProperty); }
        }

        [ValidationOption(ValidationOption.Required), Browsable(true),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public WorkflowContext __Context
        {
            get { return (WorkflowContext)base.GetValue(__ContextProperty); }
            set { base.SetValue(__ContextProperty, value); }
        }

        [ValidationOption(ValidationOption.Required), Browsable(true),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string __ListId
        {
            get { return (string)base.GetValue(__ListIdProperty); }
            set { base.SetValue(__ListIdProperty, value); }
        }


        [ValidationOption(ValidationOption.Required), Browsable(true),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string PowerShellInput
        {
            get { return (string)base.GetValue(PowerShellInputProperty); }
            set { base.SetValue(PowerShellInputProperty, value); }
        }

        [ValidationOption(ValidationOption.Optional), Browsable(true),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string PowerShellOutput
        {
            get { return (string)base.GetValue(PowerShellOutputProperty); }
            set { base.SetValue(PowerShellOutputProperty, value); }
        }



        protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext,
                                                              Exception exception)
        {
            // If an exception is thrown in the Execute method, write the exception message to the SharePoint workflow history list.
            var spService = (ISharePointService)executionContext.GetService(typeof(ISharePointService));
            spService.LogToHistoryList(WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowError, -1,
                                       TimeSpan.MinValue, "Ошибка", string.Format("Ошибка. {0}", exception.Message),
                                       string.Empty);
            return base.HandleFault(executionContext, exception);
        }
        
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            ActivityActivationReference.IsAllowed(GetType(), __Context.Web);

            // The NWContext object is used to provide internal Nintex Workflow methods context about
            // the running workflow
            var ctx = new NWContext(
                __Context,
                new Guid(__ListId),
                __ListItem,
                WorkflowInstanceId,
                CurrentWorkflowVariableValues,
                this);
            PowerShellOutput = "123";
            try
            {

                PowerShellOutput = RunScript(PowerShellInput);
            }
            catch (Exception error)
            {
                PowerShellOutput += String.Format("\r\nError in script : {0}\r\n", error.Message);
            }


            return ActivityExecutionStatus.Closed;
        }

        private string RunScript(string scriptText)
        {
            // create Powershell runspace
            Runspace runspace = RunspaceFactory.CreateRunspace();

            // open it
            runspace.Open();

            // create a pipeline and feed it the script text
            Pipeline pipeline = runspace.CreatePipeline();
            pipeline.Commands.AddScript(scriptText);

            // add an extra command to transform the script output objects into nicely formatted strings
            // remove this line to get the actual objects that the script returns. For example, the script
            // "Get-Process" returns a collection of System.Diagnostics.Process instances.
            pipeline.Commands.Add("Out-String");

            // execute the script
            Collection<PSObject> results = pipeline.Invoke();

            // close the runspace
            runspace.Close();

            // convert the script result into a single string
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject obj in results)
            {
                stringBuilder.AppendLine(obj.ToString());
            }

            return stringBuilder.ToString();
        }   
    }
}
